
#include <stdio.h>
#include <string.h>

#include "rgb2color.h"
#include "soft_dev.h"

#include "trace.h"

static uint8_t rgb2color(uint8_t r, uint8_t g, uint8_t b)
{
	if (r > 0x90) {
		uint8_t min, max;

		min = MIN(MIN(r, g), b);
		max = MAX(MAX(r, g), b);
		if (((max - min) * 100 / max) > 30)
			return COLOR_RED;
	}

	if (((r * 3 + g * 6 + 1 * b) / 10) < 0xE0)
		return COLOR_BLACK;

	return  COLOR_WITHE;
}

void png_draw_callback(PNGDRAW *draw)
{
	int i;
	
	virt_dev_drv *virt_dev = (virt_dev_drv *)draw->pUser;
	device_info_config_t *rom = (device_info_config_t *)virt_dev->dev;
	dev_soft_drv *dev = (dev_soft_drv *)virt_dev->drv;

	uint8_t buff = 0, bit;
	uint32_t color = COLOR_WITHE, offset, fill;

	if (rom->model.color == COLOR_MONOCHROME && virt_dev->disp_mode == 0x10) {
		buff = 0x00;
		for (i = 0; i < draw->iWidth / 8; i++)
			dev->data(dev, &buff, 1);

		return;
	}

	if (draw->iBpp == 1) {
		for (i = 0; i < draw->iWidth / 8; i++) {
			if (virt_dev->disp_mode == 0x10)
				buff = (rom->model.color == COLOR_MONOCHROME) ? ~draw->pPixels[i] : draw->pPixels[i];
			else
				buff = 0;

			dev->data(dev, &buff, 1);
		}

		return;
	}


	for (i = 0; i < draw->iWidth; i++) {
		if (i >  rom->model.width - 1)
			break;

		switch (draw->iPixelType) {
			case PNG_PIXEL_GRAYSCALE:
				color = draw->pPixels[i * draw->iBpp / 8] ? COLOR_BLACK : COLOR_WITHE;
				break;
			case PNG_PIXEL_INDEXED:
				if (draw->iBpp == 2) {
					offset = (i & 0x3);
					color = ((draw->pPixels[i / 4] >> ((3 - offset)) * 2) & 0x3);
					break;
				}

				if (draw->iBpp == 4) {
					offset = (i & 0x1);
					color = ((draw->pPixels[i / 2] >> ((1 - offset)) * 4) & 0xF);
					if (color > 2)
						color = COLOR_WITHE;
					break;
				}

				if (draw->iBpp == 8) {
					color = draw->pPixels[i];
					if (color > 2)
						color = COLOR_WITHE;
				}

				break;
			case PNG_PIXEL_TRUECOLOR:
				color = rgb2color(draw->pPixels[i * 3],
						draw->pPixels[i * 3 + 1],
						draw->pPixels[i * 3 + 2]);

				break;
			case PNG_PIXEL_TRUECOLOR_ALPHA:
				color = rgb2color(draw->pPixels[i * 4],
						draw->pPixels[i * 4 + 1],
						draw->pPixels[i * 4 + 2]);

				break;
		}

		if (rom->model.color == COLOR_MONOCHROME) {
			bit = (color == COLOR_BLACK) ? 1 : 0;
		} else {
			if (virt_dev->disp_mode == 0x13)
				// bit = (color != COLOR_RED) ? 0 : 1;
				bit = (color != COLOR_RED) ? 1 : 0;
			else
				bit = (color == COLOR_BLACK) ? 0 : 1;
		}

		offset = i & 0x7;
		if (offset == 0)
			buff = 0;

		buff |= (bit << (7 - offset));

		if (offset == 7)
			dev->data(dev, &buff, 1);
	}

	// if (i < rom->model.width) {
	// 	fill = (rom->model.width - i) / 8;
	// 	if (virt_dev->disp_mode == 0x13)
	// 		buff = 0x00;
	// 	else
	// 		buff = (rom->model.color == COLOR_MONOCHROME) ? 0x0 : 0xFF;

	// 	for (i = 0; i < fill; i++) {
	// 		dev->data(dev, &buff, 1);
	// 	}
	// }
	d_printf("\n");
}
